package nina.yiyou.paystub.output

import groovy.transform.PackageScope
import nina.yiyou.paystub.input.TableMetaReader

import java.awt.Graphics2D
import java.awt.Image
import java.awt.image.BufferedImage
import java.awt.image.RenderedImage

@PackageScope
class ResultImageMaker {

  ResultImageMaker(TableMetaReader.Employee employeeMeta, Image tableImg, TableMetaReader.Meta tableMeta) {
    _employeeMeta = employeeMeta
    _tableImg = tableImg
    _tableMeta = tableMeta
  }

  RenderedImage make() {
    int tableImgW = _tableImg.getWidth(null)
    int tableImgH = _tableImg.getHeight(null)

    double headerHeight = _tableMeta.headerHeight()
    int headerImgH = getImageHeight(tableImgH, headerHeight) + 1
    int rowImgH = getImageHeight(tableImgH, _employeeMeta.lineHeight())

    int resultImgH = headerImgH + rowImgH
    def resultImg = new BufferedImage(tableImgW, resultImgH, BufferedImage.TYPE_INT_RGB)

    Graphics2D graphic = resultImg.createGraphics()
    graphic.drawImage(_tableImg, 0, 0, null)

    int readY = (tableImgH * (headerHeight + getLineOffset(_employeeMeta.lineIndex()))).intValue() + 1
    drawRow(graphic, headerImgH, readY, rowImgH)

    graphic.dispose()
    return resultImg
  }

  private int getImageHeight(int totalHeight, double heightRatio) {
    return Math.round(totalHeight * heightRatio).intValue()
  }

  private double getLineOffset(int lineIndex) {
    return _tableMeta.rowList()
        .findAll { it.lineIndex() < lineIndex }
        .collect { it.lineHeight() }
        .sum(0) as double
  }

  private void drawRow(Graphics2D g, int drawY, int readY, int rowH) {
    int tableImgW = _tableImg.getWidth(null)
    g.drawImage(_tableImg, 0, drawY, tableImgW, drawY + rowH, 0, readY, tableImgW, readY + rowH, null)
  }

  private final TableMetaReader.Employee _employeeMeta

  private final Image _tableImg
  private final TableMetaReader.Meta _tableMeta
}
